#pragma once

#include<iostream>
#include<sys/epoll.h>
#include<unistd.h>
#include"Log.hpp"
#include"Common.hpp"
using namespace LogModule;


class Epoller
{
public:
    Epoller():_epfd(-1)
    {
        _epfd = epoll_create(128);
        if(_epfd < 0)
        {
            LOG(LogLevel::FATAL) << "epoll_create error...";
            exit(EPOLL_CREATE_ERROR);
        }
        LOG(LogLevel::DEBUG) << "epoll_create success: " <<_epfd;
    }
    void AddEvent(int sockfd,uint32_t events)
    {
        struct epoll_event ev;
        ev.data.fd = sockfd;
        ev.events = events;//把指定的文件描述符对应的事件添加到内核
        int n = epoll_ctl(_epfd,EPOLL_CTL_ADD,sockfd,&ev);
        if(n < 0)
        {
            LOG(LogLevel::FATAL) << "epoll_ctl error...";
            return;
        }
        LOG(LogLevel::DEBUG) << "epoll_ctl success: " << sockfd;
    }
    void ModEvent(int sockfd,uint32_t events)
    {
        struct epoll_event ev;
        ev.data.fd = sockfd;
        ev.events = events;
        int n = epoll_ctl(_epfd,EPOLL_CTL_MOD,sockfd,&ev);
        if(n < 0)
        {
            LOG(LogLevel::FATAL) << "epoll_ctl error...";
            return;
        }
        LOG(LogLevel::DEBUG) << "epoll_ctl success: " << sockfd;
    }
    void DelEvent(int sockfd)
    {
        struct epoll_event ev;
        ev.data.fd = sockfd;
        ev.events = 0;
        int n = epoll_ctl(_epfd,EPOLL_CTL_DEL,sockfd,&ev);
        if(n < 0)
        {
            LOG(LogLevel::FATAL) << "epoll_ctl error...";
            return;
        }
        LOG(LogLevel::DEBUG) << "epoll_ctl success: " << sockfd;
    }
    int WaitEvents(struct epoll_event revs[],int maxnum,int timeout)
    {
        int n = epoll_wait(_epfd,revs,maxnum,timeout);
        if(n < 0)
        {
            LOG(LogLevel::WARING) << "epoll_wait error";
        }
        else if(n == 0)
        {
            LOG(LogLevel::WARING) << "epoll_wait timeout";
        }
        else
        {
            
        }
        return n;
    }
    ~Epoller()
    {
        if(_epfd >= 0)
        {
            close(_epfd);
        }
    }
private:
    int _epfd;
};